<?php
/**
 * Create By: PhpStorm
 * User: niechenguang
 * File: Circle.php
 * Date: 2017/1/2
 * Time: 23:13
 */

namespace app\api\model\page\note;

use app\api\model\dao\ContributionRank;
use app\api\model\dao\Note;
use app\api\model\dao\Circle;
use app\api\model\dao\NoteReply;
use app\api\model\dao\TaskLog;
use app\api\model\dao\UserAccount;
use app\api\model\dao\UserCurrency;
use app\api\model\dao\WordForbidden;
use app\api\model\data\currency\ConsumeCurrency;
use app\api\model\data\note\NoteData;
use app\library\Common;
use app\library\Error;
use app\library\Flag;
use app\library\PageBase;
use think\Exception;
use think\Validate;
use think\Log;

class AddNote extends PageBase
{

    private $objNote;
    private $objCircle;
    private $objTaskLog;
    private $objNoteData;
    private $objUserCurrency;
    private $objNoteReply;
    private $objContributionRank;
    private $objUserAccount;
    private $objWordForbidden;

    public function __construct()
    {
        parent::__construct();

        $this->objNote = new Note();
        $this->objCircle = new Circle();
        $this->objTaskLog = new TaskLog();
        $this->objNoteData = new NoteData();
        $this->objUserCurrency = new ConsumeCurrency();
        $this->objNoteReply = new NoteReply();
        $this->objContributionRank = new ContributionRank();
        $this->objUserAccount = new UserAccount();
        $this->objWordForbidden = new WordForbidden();
    }

    /**
     * @param $param
     * @return array|bool
     * @DESC 验证接口字段
     */
    public function checkParam($param)
    {
        $rule = [
            'cir_id' => 'require',
            'title' => 'require|min:4',
            'content' => 'require',
        ];
        $msg = [
            'cir_id.require' => '帖子所属哪个圈子',
            'title.require' => '帖子标题不能为空',
            'title.min' => '帖子标题不得少于4个字符',
            'content.require' => '帖子内容不能为空',
        ];

        $validate = new Validate($rule, $msg);
        $result = $validate->check($param);
        if (!$result) {
            return $validate->getError();
        }
        return '';
    }

    public function myExcute($param)
    {
        $ret = $this->checkToken($param);
        if (false === $ret) {
            throw new Exception('check token fail...', Error::ERR_NO_AUTH);
        }

        // 1、获取用户信息
        $user_account = $this->objUserAccount->getUserAccount(['user_id' => $this->user_id]);
        if (false === $user_account) {
            Log::error(__METHOD__ . 'get user account from db fail. [user_id: ' . $param['user_id'] . ']');
            return $this->getRes(Error::ERR_SYS);
        }
        if (empty($user_account)) {
            return $this->getRes(Error::ERR_USER_NOT_EXIST);
        }
        $user_account = $user_account[0];

        if ($user_account['silence_time'] > time()) {
            return $this->getRes(Error::ERR_USER_IS_SILENCE);
        }

        // 1、参数校验
        $ret = $this->checkParam($param);
        if ($ret) {
            throw new Exception($ret, Error::ERR_PARAM);
        }

        // 2、获取圈子
        $ret = $this->getCircleInfoFromDB($param['cir_id']);
        if (false === $ret) {
            throw new Exception('get circle info from db fail. [circle_id: ' . $param['cir_id'] . ']', Error::ERR_SYS);
        }

        if (empty($ret)) {
            throw new Exception('circle is empty. [circle_id: ' . $param['cir_id'] . ']', Error::ERR_CIRCLE_NOT_EXIST);
        }

        // 3、校验是否被删除
        if (Flag::CONST_CIRCLE_DELETED == $ret['is_delete']) {
            throw new Exception('circle is deleted', Error::ERR_CIRCLE_DELETED);
        }

        // 4、校验是否审核
        if (Flag::CONST_CIRCLE_APPROVE_PASS != $ret['approve_status']) {
            throw new Exception('circle is not approve', Error::ERR_CIRCLE_APPROVE_NOT);
        }

        // 判断是否含有敏感词汇
        $forbidden_word = $this->objWordForbidden->getAllWord();
        if (!empty($forbidden_word)) {
            $has_forbidden_word = false;
            foreach ($forbidden_word as $word) {
                if ((substr_count($param['content'], $word['word']) > 0) || (substr_count($param['title'], $word['word']) > 0)) {
                    $has_forbidden_word = true;
                    break;
                }
            }
            if ($has_forbidden_word) {
                throw new Exception('note has forbidden word', Error::ERR_HAS_FORBIDDEN_WORD);
            }
        }

        // 5、构造帖子参数
        $input = [
            'category_id' => $ret['category_id'],
            'cir_id' => intval($param['cir_id']),
            'title' => trim($param['title']),
            'content' => trim($param['content']),
            'date' => date('Ymd'),
            'creator' => $this->user_id,
            'update_time' => time(),
            'create_time' => time(),
        ];

        if (isset($param['pic']) && !empty($param['pic'])) {
            $input['pic'] = urlencode(trim($param['pic']));
        }

        if (isset($param['original']) && !empty($param['original'])) {
            $input['original'] = intval($param['original']);
        }

        $insertID = $this->objNote->addNote($input);
        if (false === $insertID) {
            throw new Exception('add note fail...[input: ' . json_encode($input) . ']', Error::ERR_SYS);
        }

        $hasWord = [];

        // 切词
        $words = \app\library\Common::scws($param['title']);
        if (!empty($words)) {
            foreach ($words as $word) {
                if (in_array($word, $hasWord)) {
                    continue;
                }
                $hasWord[] = $word;
                $word_note[] = [
                    'word' => $word,
                    'type' => \app\library\Flag::CONST_WORD_TYPE_NOTE,
                    'obj_id' => $insertID,
                ];
            }
        }
        $words = \app\library\Common::scws($param['content']);
        if (!empty($words)) {
            foreach ($words as $word) {
                if (in_array($word, $hasWord)) {
                    continue;
                }
                $hasWord[] = $word;
                $word_note[] = [
                    'word' => $word,
                    'type' => \app\library\Flag::CONST_WORD_TYPE_NOTE,
                    'obj_id' => $insertID,
                ];
            }
        }
        if (!empty($word_note)) {
            $objWordLibrary = new \app\api\model\dao\WordLibrary();
            $ret = $objWordLibrary->addWordBatch($word_note);
            if (false === $ret) {
                \think\Log::error(__METHOD__ . ' scws fail.');
            }
        }

        Common::addIntegral($this->user_id, 'note');

        // 增加贡献值
        $this->objContributionRank->add($param['cir_id'], $this->user_id, Flag::$contribution_map['note']);

        // 看是否存在任务完成
        $ret = $this->task($this->user_id);
        if (false === $ret) {
            \think\Log::error(__METHOD__ . ' check task fail.');
        }
    }

    /**
     * 从数据库中获取圈子详情
     *
     * @param $cir_id
     * @return bool|false|\PDOStatement|string|\think\Collection
     */
    public function getCircleInfoFromDB($cir_id)
    {
        if (!$cir_id) {
            return false;
        }
        $arrCond = [
            'id' => ['=', $cir_id]
        ];
        $ret = $this->objCircle->getCircle($arrCond);
        if (false === $ret) {
            return false;
        }
        if (empty($ret)) {
            return [];
        }
        $ret = $ret[0];
        return $ret;
    }

    public function task($userid)
    {

        $date = date('Ymd');

        $arrCond = [
            'task_id' => ['=', 2],
            'userid' => $userid,
        ];
        $ret = $this->objTaskLog->getTaskLog($arrCond);
        if (false === $ret) {
            Log::error(__METHOD__ . ' get task log fail.[cond:' . json_encode($arrCond) . ']');
            return false;
        }
        if (empty($ret)) {
            // 判断是否满足完成任务条件
            $note_cnt = $this->objNoteData->mineNoteCount($userid);
            if ($note_cnt >= Flag::CONST_TASK_NEW_NOTE_COUNT) {
                $arrInput = [
                    'task_id' => 2,
                    'userid' => $userid,
                    'date' => $date,
                ];
                $ret = $this->objTaskLog->addTaskLog($arrInput);
                if (false === $ret) {
                    Log::error(__METHOD__ . ' add task log fail.[param:' . json_encode($arrInput) . ']');
                    return false;
                }
                Common::addIntegral($userid, 'task_note');
            }
        }

        $arrCond = [
            'task_id' => ['=', 100],
            'userid' => $userid,
            'date' => $date
        ];
        $ret = $this->objTaskLog->getTaskLog($arrCond);
        if (false === $ret) {
            Log::error(__METHOD__ . ' get task log fail.[cond:' . json_encode($arrCond) . ']');
            return false;
        }
        if (empty($ret)) {
            // 判断是否满足完成任务条件
            $note_cnt = $this->objNoteData->mineNoteCount($userid, $date);
            if ($note_cnt >= Flag::CONST_TASK_DAILY_NOTE_COUNT) {
                $arrInput = [
                    'task_id' => 100,
                    'userid' => $userid,
                    'date' => $date,
                ];
                $ret = $this->objTaskLog->addTaskLog($arrInput);
                if (false === $ret) {
                    Log::error(__METHOD__ . ' add task log fail.[param:' . json_encode($arrInput) . ']');
                    return false;
                }
                Common::addIntegral($userid, 'task_daily_note');
            }
        }

        return true;
    }
}
